﻿/*************************************************************************************
 * 工    具：  HK_SimpleVideoCtrl
 * 
 * 描    述：  简易视频播放工具
 * 
 * 版    本：  V1.5
 * 作    者：  谭潇杰、京产肠饭
 * 
 * 创    建：  2021/09/15  V1.0
 *
 * 更    新：  2025/03/29  V1.1
 *             1.功能优化：增加播放器状态管理，防止视频切换时的状态冲突
 *             2.代码优化：对 videoPlayer 的prepareCompleted事件进行了优化，避免重复注册    
 *             3.功能优化：增强平台兼容性
 *             4.性能优化：增强RenderTexture资源管理，防止纹理资源泄露
 *
 *             2025/03/30  V1.2
 *             1.功能优化：合并视频暂停功能，减少无用脚本
 *             2.代码优化：整合协程方法，作为局部函数增强代码内聚性
 *
 *             2025/04/08  V1.3
 *             1.功能新增：增加 SetPlaybackSpeed(float speed) 方法，设置播放速度
 * 
 *             2025/08/15  V1.4
 *             1.代码优化：优化资源查找与配置
 *             2.功能新增：新增 isCanCtrlByClick 变量，控制是否可点击操控
 *             3.功能新增：新增 SetVolume(float volume) 方法，设置音量
 *             4.功能新增：新增 Event_HKSimpleVideo_OnVideoCompleted 事件，视频播放完成时触发，可在外界注册
 *
 *             2025/10/12  V1.5
 *             1.功能新增：新增 SetMute(bool isMute) 方法，设置是否静音
 *             2.功能新增：新增 SetFastFowardOrRewind(float ratio) 方法，设置快进或快退
 *             3.Bug修复：修复 URL视频下，Event_HKSimpleVideo_OnVideoCompleted 事件触发的Bug
 *
 * 链    接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using System;
using System.Collections;
using QFramework;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine.Video;

namespace HKTools
{
    public class HK_SimpleVideoCtrl : HKVideo_BaseController, IPointerDownHandler
    {
        [Header("VideoPlayer组件："), SerializeField] VideoPlayer videoPlayer;
        [Header("视频暂停提示："), SerializeField] Image img_Pause;
        [Header("是否可点击操控？"), SerializeField] bool isCanCtrlByClick = true;

        public event Action OnVideoCompleted;
        public event Action<float> OnVideoProgressChanged;

        bool isPaused;

        public float CurrentVoluem
        {
            get
            {
                if (videoPlayer.audioTrackCount > 0)
                {
                    return videoPlayer.GetDirectAudioVolume(0);
                }
                return 0;
            }
        }
        
        float currentVolume = 0;

        double videoDuration;

        void OnEnable()
        {
            if (img_Pause == null)
                img_Pause = transform.Find("Pause_Img")?.GetComponent<Image>();

            img_Pause?.Hide();

            if (videoPlayer.audioTrackCount > 0)
            {
                currentVolume = videoPlayer.GetDirectAudioVolume(0);
            }

            if (videoPlayer.targetTexture != null && videoPlayer.targetTexture.IsCreated())
            {
                videoPlayer.targetTexture.Release();
            }

            videoPlayer.loopPointReached += OnVideoLoopPointReached;
        }

        void OnDisable()
        {
            StopVideo();

            videoPlayer.loopPointReached -= OnVideoLoopPointReached;
        }

        void OnVideoLoopPointReached(VideoPlayer videoPlayer)
        {
            string videoClipName = "";

            if (videoPlayer.source == VideoSource.VideoClip)
                videoClipName = videoPlayer.clip.name;
            else
                videoClipName = videoPlayer.url;

            this.SendEvent(new Event_HKSimpleVideo_OnVideoCompleted()
            {
                _videoClipName = videoClipName
            });
        }

        public void OnPointerDown(PointerEventData eventData)
        {
            if (!isCanCtrlByClick)
                return;

            PauseVideo();
        }

        /// <summary>
        /// 通过 VideoClip 播放视频
        /// </summary>
        public void PlayClipVideo(VideoClip videoClip, bool isLooping = false)
        {
            PlayVideo(() =>
            {
                if (videoPlayer.source != VideoSource.VideoClip)
                    videoPlayer.source = VideoSource.VideoClip;

                if (videoClip != null)
                    videoPlayer.clip = videoClip;

                SetupVideoPlayer(isLooping);
            });
        }

        /// <summary>
        /// 通过 URL 播放视频
        /// </summary>
        public void PlayURLVideo(string url, bool isLooping = false)
        {
            PlayVideo(() =>
            {
                if (videoPlayer.source != VideoSource.Url)
                    videoPlayer.source = VideoSource.Url;

                if (!string.IsNullOrEmpty(url))
                    videoPlayer.url = url;

                SetupVideoPlayer(isLooping);
            });
        }

        /// <summary>
        /// 通过 StreamingAssets 播放视频
        /// </summary>
        public void PlayStreamingAssetsVideo(string videoName, bool isLooping = false)
        {
            PlayVideo(() =>
            {
                if (videoPlayer.source != VideoSource.Url)
                    videoPlayer.source = VideoSource.Url;

#if UNITY_ANDROID && !UNITY_EDITOR
                var filePath = $"file://{System.IO.Path.Combine(Application.streamingAssetsPath, videoName)}";
#else
                var filePath = System.IO.Path.Combine(Application.streamingAssetsPath, videoName);
#endif

                videoPlayer.url = filePath;

                SetupVideoPlayer(isLooping);
            });
        }

        /// <summary>
        /// 设置播放速度
        /// </summary>
        /// <param name="speed"> 播放速度 </param>
        public void SetPlaybackSpeed(float speed)
        {
            videoPlayer.playbackSpeed = speed;
        }

        /// <summary>
        /// 设置快进或快退
        /// </summary>
        /// <param name="ratio"></param>
        public void SetFastFowardOrRewind(float ratio)
        {
            // 让videoPlayer快进或快退
            videoPlayer.time = videoPlayer.time + ratio * videoDuration;
        }

        /// <summary>
        /// 设置音量
        /// </summary>
        /// <param name="volume"> 音量大小 (0-1之间) </param>
        public void SetVolume(float volume)
        {
            if (videoPlayer.audioTrackCount == 0)
                return;

            currentVolume = Mathf.Clamp01(volume);
            videoPlayer.SetDirectAudioVolume(0, currentVolume);
        }

        void PlayVideo(Action playVideoAction)
        {
            IEnumerator IE_DelayedPlay()
            {
                yield return null;
                playVideoAction?.Invoke();
            }

            if (videoPlayer.isPlaying || videoPlayer.isPrepared)
            {
                StopVideo();
                StartCoroutine(IE_DelayedPlay());
            }
            else
            {
                playVideoAction?.Invoke();
            }
        }

        void SetupVideoPlayer(bool isLooping = false)
        {
            SetPlaybackSpeed(1);

            videoPlayer.isLooping = isLooping;
            img_Pause.Hide();
            videoPlayer.SetDirectAudioMute(0, false);

            videoPlayer.prepareCompleted -= OnPrepareCompleted;
            videoPlayer.prepareCompleted += OnPrepareCompleted;

            videoPlayer.Prepare();
            isPaused = false;
        }

        void OnPrepareCompleted(VideoPlayer source)
        {
            try
            {
                videoPlayer.Play();
                videoDuration = videoPlayer.length;
            }
            finally
            {
                videoPlayer.prepareCompleted -= OnPrepareCompleted; // 重要：解除事件绑定
            }
        }

        /// <summary>
        /// 暂停视频
        /// </summary>
        public void PauseVideo()
        {
            if (videoPlayer.clip == null && string.IsNullOrEmpty(videoPlayer.url))
                return;

            isPaused = !isPaused;
            img_Pause.gameObject.SetActive(isPaused);

            if (!isPaused)
                videoPlayer.Play();
            else
                videoPlayer.Pause();
        }

        /// <summary>
        /// 停止播放
        /// </summary>
        public void StopVideo()
        {
            videoPlayer.Stop();

            // 添加目标纹理存在检查
            if (videoPlayer.targetTexture != null)
            {
                videoPlayer.targetTexture.Release(); // 释放 GPU 资源
                // 添加纹理重置操作
                RenderTexture.active = null;         // 清除当前激活的 RenderTexture
            }

            videoPlayer.clip = null;
            videoPlayer.url = string.Empty;
            isPaused = false;
            img_Pause.Hide();
        }

        public void SetMute(bool isMute)
        {
            if (isMute)
            {
                videoPlayer.SetDirectAudioMute(0, true);
            }
            else
            {
                videoPlayer.SetDirectAudioMute(0, false);
            }
        }
    }
}